package model

import (
	"crypto/md5"
	"fmt"
	"github.com/labstack/echo"
	"maki/config"
	"maki/utils"
	"strconv"
	"time"
)

// User model.
type User struct {
	Model

	Username  string `gorm:"size:32" json:"username"`
	Password  string `gorm:"size:255" json:"-"`
	Email     string `gorm:"size:32" json:"-"`
	Nickname  string `gorm:"size:32" json:"nickname"`
	AvatarURL string `gorm:"size:255" json:"avatarURL"`
	Locale    string `gorm:"size:32" json:"locale"`
	Role      int    `json:"-" gorm:"default:1"`
}

// User roles.
const (
	UserRoleAnonymous = 0
	UserRoleNormal    = 1
	UserRoleAdmin     = 2
)

// CheckPassword 验证密码是否正确
func (user *User) CheckPassword(password string) bool {
	if password == "" || user.Password == "" {
		return false
	}
	return user.EncryptPassword(password, user.Salt()) == user.Password
}

// SetPassword 设置密码
func (user *User) SetPassword(password string) {
	user.Password = ""
	salt := user.Salt()
	user.Password = user.EncryptPassword(password, salt)
	return
}

// Salt 每个用户都有一个不同的盐
func (user *User) Salt() string {
	var userSalt string
	if user.Password == "" {
		userSalt = strconv.Itoa(int(time.Now().Unix()))
	} else {
		userSalt = user.Password[0:10]
	}
	return userSalt
}

// EncryptPassword 给密码加密
func (user *User) EncryptPassword(password, salt string) (hash string) {
	password = fmt.Sprintf("%x", md5.Sum([]byte(password)))
	hash = salt + password + config.ServerConfig.PassSalt
	hash = salt + fmt.Sprintf("%x", md5.Sum([]byte(hash)))
	return
}

// IsAdmin is user a admin
func (user *User) IsAdmin() bool {
	return user.Role == UserRoleAdmin
}

func GetUser(ctx echo.Context) (*User, error) {
	u := ctx.Get("user")
	if user, ok := u.(*User); !ok {
		return nil, utils.ErrUserNotLogin
	} else {
		return user, nil
	}
}

func CreateSampleUser(username, password string) (user *User) {
	user = &User{
		Username: username,
		Email:    "test@test.com",
	}
	user.SetPassword(password)
	if status := DB.FirstOrCreate(user); status.Error != nil {
		panic(status.Error)
	}
	return user
}
